Ejemplo n.º 1
0
def calculateLorenzDifference(sim_wealth, weights, percentiles, target_levels):
    '''
    Calculates the sum of squared differences between the simulatedLorenz curve
    at the specified percentile levels and the target Lorenz levels.
    
    Parameters
    ----------
    sim_wealth : numpy.array
        Array with simulated wealth values.
    weights : numpy.array
        List of weights for each row of sim_wealth.
    percentiles : [float]
        Points in the distribution of wealth to match.
    target_levels : np.array
        Actual U.S. Lorenz curve levels at the specified percentiles.
        
    Returns
    -------
    distance : float
        Sum of squared distances between simulated and target Lorenz curves.
    '''
    sim_lorenz = getLorenzShares(sim_wealth,
                                 weights=weights,
                                 percentiles=percentiles)
    distance = sum((100 * sim_lorenz - 100 * target_levels)**2)
    return distance
Ejemplo n.º 2
0
def makeLorenzFig(real_wealth, real_weights, sim_wealth, sim_weights):
    '''
    Produces a Lorenz curve for the distribution of wealth, comparing simulated
    to actual data.  A sub-function of makeCSTWresults().
    
    Parameters
    ----------
    real_wealth : np.array
        Data on household wealth.
    real_weights : np.array
        Weighting array of the same size as real_wealth.
    sim_wealth : np.array
        Simulated wealth holdings of many households.
    sim_weights :np.array
        Weighting array of the same size as sim_wealth.
        
    Returns
    -------
    these_percents : np.array
        An array of percentiles of households, by wealth.
    real_lorenz : np.array
        Lorenz shares for real_wealth corresponding to these_percents.
    sim_lorenz : np.array
        Lorenz shares for sim_wealth corresponding to these_percents.
    '''
    these_percents = np.linspace(0.0001, 0.9999, 201)
    real_lorenz = getLorenzShares(real_wealth,
                                  weights=real_weights,
                                  percentiles=these_percents)
    sim_lorenz = getLorenzShares(sim_wealth,
                                 weights=sim_weights,
                                 percentiles=these_percents)
    plt.plot(100 * these_percents, real_lorenz, '-k', linewidth=1.5)
    plt.plot(100 * these_percents, sim_lorenz, '--k', linewidth=1.5)
    plt.xlabel('Wealth percentile', fontsize=14)
    plt.ylabel('Cumulative wealth ownership', fontsize=14)
    plt.title('Simulated vs Actual Lorenz Curves', fontsize=16)
    plt.legend(('Actual', 'Simulated'), loc=2, fontsize=12)
    plt.ylim(-0.01, 1)
    plt.show()
    return (these_percents, real_lorenz, sim_lorenz)
Ejemplo n.º 3
0
def makeLorenzFig(real_wealth,real_weights,sim_wealth,sim_weights):
    '''
    Produces a Lorenz curve for the distribution of wealth, comparing simulated
    to actual data.  A sub-function of makeCSTWresults().
    
    Parameters
    ----------
    real_wealth : np.array
        Data on household wealth.
    real_weights : np.array
        Weighting array of the same size as real_wealth.
    sim_wealth : np.array
        Simulated wealth holdings of many households.
    sim_weights :np.array
        Weighting array of the same size as sim_wealth.
        
    Returns
    -------
    these_percents : np.array
        An array of percentiles of households, by wealth.
    real_lorenz : np.array
        Lorenz shares for real_wealth corresponding to these_percents.
    sim_lorenz : np.array
        Lorenz shares for sim_wealth corresponding to these_percents.
    '''
    these_percents = np.linspace(0.0001,0.9999,201)
    real_lorenz = getLorenzShares(real_wealth,weights=real_weights,percentiles=these_percents)
    sim_lorenz = getLorenzShares(sim_wealth,weights=sim_weights,percentiles=these_percents)
    plt.plot(100*these_percents,real_lorenz,'-k',linewidth=1.5)
    plt.plot(100*these_percents,sim_lorenz,'--k',linewidth=1.5)
    plt.xlabel('Wealth percentile',fontsize=14)
    plt.ylabel('Cumulative wealth ownership',fontsize=14)
    plt.title('Simulated vs Actual Lorenz Curves',fontsize=16)
    plt.legend(('Actual','Simulated'),loc=2,fontsize=12)
    plt.ylim(-0.01,1)
    plt.show()
    return (these_percents,real_lorenz,sim_lorenz)
Ejemplo n.º 4
0
def calculateLorenzDifference(sim_wealth,weights,percentiles,target_levels):
    '''
    Calculates the sum of squared differences between the simulatedLorenz curve
    at the specified percentile levels and the target Lorenz levels.
    
    Parameters
    ----------
    sim_wealth : numpy.array
        Array with simulated wealth values.
    weights : numpy.array
        List of weights for each row of sim_wealth.
    percentiles : [float]
        Points in the distribution of wealth to match.
    target_levels : np.array
        Actual U.S. Lorenz curve levels at the specified percentiles.
        
    Returns
    -------
    distance : float
        Sum of squared distances between simulated and target Lorenz curves.
    '''
    sim_lorenz = getLorenzShares(sim_wealth,weights=weights,percentiles=percentiles)
    distance = sum((100*sim_lorenz-100*target_levels)**2)
    return distance
Ejemplo n.º 5
0
    def calcStats(self, aLvlNow, pLvlNow, MPCnow, TranShkNow, EmpNow, t_age,
                  LorenzBool, ManyStatsBool):
        '''
        Calculate various statistics about the current population in the economy.
        
        Parameters
        ----------
        aLvlNow : [np.array]
            Arrays with end-of-period assets, listed by each ConsumerType in self.agents.
        pLvlNow : [np.array]
            Arrays with permanent income levels, listed by each ConsumerType in self.agents.
        MPCnow : [np.array]
            Arrays with marginal propensity to consume, listed by each ConsumerType in self.agents.
        TranShkNow : [np.array]
            Arrays with transitory income shocks, listed by each ConsumerType in self.agents.
        EmpNow : [np.array]
            Arrays with employment states: True if employed, False otherwise.
        t_age : [np.array]
            Arrays with periods elapsed since model entry, listed by each ConsumerType in self.agents.
        LorenzBool: bool
            Indicator for whether the Lorenz target points should be calculated.  Usually False,
            only True when DiscFac has been identified for a particular nabla.
        ManyStatsBool: bool
            Indicator for whether a lot of statistics for tables should be calculated. Usually False,
            only True when parameters have been estimated and we want values for tables.
            
        Returns
        -------
        None
        '''
        # Combine inputs into single arrays
        aLvl = np.hstack(aLvlNow)
        pLvl = np.hstack(pLvlNow)
        age = np.hstack(t_age)
        TranShk = np.hstack(TranShkNow)
        Emp = np.hstack(EmpNow)

        # Calculate the capital to income ratio in the economy
        CohortWeight = self.PopGroFac**(-age)
        CapAgg = np.sum(aLvl * CohortWeight)
        IncAgg = np.sum(pLvl * TranShk * CohortWeight)
        KtoYnow = CapAgg / IncAgg
        self.KtoYnow = KtoYnow

        # Store Lorenz data if requested
        self.LorenzLong = np.nan
        if LorenzBool:
            order = np.argsort(aLvl)
            aLvl = aLvl[order]
            CohortWeight = CohortWeight[order]
            wealth_shares = getLorenzShares(aLvl,
                                            weights=CohortWeight,
                                            percentiles=self.LorenzPercentiles,
                                            presorted=True)
            self.Lorenz = wealth_shares
            if ManyStatsBool:
                self.LorenzLong = getLorenzShares(aLvl,
                                                  weights=CohortWeight,
                                                  percentiles=np.arange(
                                                      0.01, 1.0, 0.01),
                                                  presorted=True)
        else:
            self.Lorenz = np.nan  # Store nothing if we don't want Lorenz data

        # Calculate a whole bunch of statistics if requested
        if ManyStatsBool:
            # Reshape other inputs
            MPC = np.hstack(MPCnow)

            # Sort other data items if aLvl and CohortWeight were sorted
            if LorenzBool:
                pLvl = pLvl[order]
                MPC = MPC[order]
                TranShk = TranShk[order]
                age = age[order]
                Emp = Emp[order]
            aNrm = aLvl / pLvl  # Normalized assets (wealth ratio)
            IncLvl = TranShk * pLvl  # Labor income this period

            # Calculate overall population MPC and by subpopulations
            #MPCsixmonths = 1.0 - 0.25*((1.0 - MPC) + (1.0 - MPC)**2 + (1.0 - MPC)**3 + (1.0 - MPC)**4)
            MPCsixmonths = 1.0 - (1.0 - MPC)**2
            self.MPCall = np.sum(
                MPCsixmonths * CohortWeight) / np.sum(CohortWeight)
            employed = Emp
            unemployed = np.logical_not(employed)
            if self.T_retire > 0:  # Adjust for the lifecycle model, where agents might be retired instead
                unemployed = np.logical_and(unemployed, age < self.T_retire)
                employed = np.logical_and(employed, age < self.T_retire)
                retired = age >= self.T_retire
            else:
                retired = np.zeros_like(unemployed, dtype=bool)
            self.MPCunemployed = np.sum(
                MPCsixmonths[unemployed] * CohortWeight[unemployed]) / np.sum(
                    CohortWeight[unemployed])
            self.MPCemployed = np.sum(
                MPCsixmonths[employed] * CohortWeight[employed]) / np.sum(
                    CohortWeight[employed])
            self.MPCretired = np.sum(
                MPCsixmonths[retired] * CohortWeight[retired]) / np.sum(
                    CohortWeight[retired])
            self.MPCbyWealthRatio = calcSubpopAvg(MPCsixmonths, aNrm,
                                                  self.cutoffs, CohortWeight)
            self.MPCbyIncome = calcSubpopAvg(MPCsixmonths, IncLvl,
                                             self.cutoffs, CohortWeight)

            # Calculate the wealth quintile distribution of "hand to mouth" consumers
            quintile_cuts = getPercentiles(aLvl,
                                           weights=CohortWeight,
                                           percentiles=[0.2, 0.4, 0.6, 0.8])
            wealth_quintiles = np.ones(aLvl.size, dtype=int)
            wealth_quintiles[aLvl > quintile_cuts[0]] = 2
            wealth_quintiles[aLvl > quintile_cuts[1]] = 3
            wealth_quintiles[aLvl > quintile_cuts[2]] = 4
            wealth_quintiles[aLvl > quintile_cuts[3]] = 5
            MPC_cutoff = getPercentiles(
                MPCsixmonths, weights=CohortWeight, percentiles=[
                    2.0 / 3.0
                ])  # Looking at consumers with MPCs in the top 1/3
            these = MPCsixmonths > MPC_cutoff
            in_top_third_MPC = wealth_quintiles[these]
            temp_weights = CohortWeight[these]
            hand_to_mouth_total = np.sum(temp_weights)
            hand_to_mouth_pct = []
            for q in range(1, 6):
                hand_to_mouth_pct.append(
                    np.sum(temp_weights[in_top_third_MPC == q]) /
                    hand_to_mouth_total)
            self.HandToMouthPct = np.array(hand_to_mouth_pct)

        else:  # If we don't want these stats, just put empty values in history
            self.MPCall = np.nan
            self.MPCunemployed = np.nan
            self.MPCemployed = np.nan
            self.MPCretired = np.nan
            self.MPCbyWealthRatio = np.nan
            self.MPCbyIncome = np.nan
            self.HandToMouthPct = np.nan
Ejemplo n.º 6
0
    MrkvArray[t + 1, 0] = 1.0

    w, v = np.linalg.eig(np.transpose(MrkvArray))
    idx = (np.abs(w - 1.0)).argmin()
    x = v[:, idx].astype(float)
    AgeDstn = (x / np.sum(x))
    return AgeDstn


# Set targets for K/Y and the Lorenz curve based on the data
if Params.do_liquid:
    lorenz_target = np.array([0.0, 0.004, 0.025, 0.117])
    KY_target = 6.60
else:  # This is hacky until I can find the liquid wealth data and import it
    lorenz_target = getLorenzShares(Params.SCF_wealth,
                                    weights=Params.SCF_weights,
                                    percentiles=Params.percentiles_to_match)
    lorenz_long_data = np.hstack(
        (np.array(0.0),
         getLorenzShares(Params.SCF_wealth,
                         weights=Params.SCF_weights,
                         percentiles=np.arange(0.01, 1.0,
                                               0.01).tolist()), np.array(1.0)))
    #lorenz_target = np.array([-0.002, 0.01, 0.053,0.171])
    KY_target = 10.26

# Make AgentTypes for estimation
if Params.do_lifecycle:
    DropoutType = cstwMPCagent(**Params.init_dropout)
    DropoutType.AgeDstn = calcStationaryAgeDstn(DropoutType.LivPrb, True)
    HighschoolType = deepcopy(DropoutType)
Ejemplo n.º 7
0
        j += 1


# Only run below this line if module is run rather than imported:
if __name__ == "__main__":
    # =================================================================
    # ====== Make the list of consumer types for estimation ===========
    #==================================================================

    # Set target Lorenz points and K/Y ratio (MOVE THIS TO SetupParams)
    if Params.do_liquid:
        lorenz_target = np.array([0.0, 0.004, 0.025, 0.117])
        KY_target = 6.60
    else:  # This is hacky until I can find the liquid wealth data and import it
        lorenz_target = getLorenzShares(
            Params.SCF_wealth,
            weights=Params.SCF_weights,
            percentiles=Params.percentiles_to_match)
        #lorenz_target = np.array([-0.002, 0.01, 0.053,0.171])
        KY_target = 10.26

    # Make a vector of initial wealth-to-permanent income ratios
    a_init = drawDiscrete(N=Params.sim_pop_size,
                          P=Params.a0_probs,
                          X=Params.a0_values,
                          seed=Params.a0_seed)

    # Make the list of types for this run, whether infinite or lifecycle
    if Params.do_lifecycle:
        # Make cohort scaling array
        cohort_scale = Params.TFP_growth**(-np.arange(Params.total_T + 1))
        cohort_scale_array = np.tile(
Ejemplo n.º 8
0
        this_type.update()
        j += 1   
   

# Only run below this line if module is run rather than imported:
if __name__ == "__main__":
    # =================================================================
    # ====== Make the list of consumer types for estimation ===========
    #==================================================================
    
    # Set target Lorenz points and K/Y ratio (MOVE THIS TO SetupParams)
    if Params.do_liquid:
        lorenz_target = np.array([0.0, 0.004, 0.025,0.117])
        KY_target = 6.60
    else: # This is hacky until I can find the liquid wealth data and import it
        lorenz_target = getLorenzShares(Params.SCF_wealth,weights=Params.SCF_weights,percentiles=Params.percentiles_to_match)
        #lorenz_target = np.array([-0.002, 0.01, 0.053,0.171])
        KY_target = 10.26
       
    # Make a vector of initial wealth-to-permanent income ratios
    a_init = drawDiscrete(N=Params.sim_pop_size,P=Params.a0_probs,X=Params.a0_values,seed=Params.a0_seed)
                                             
    # Make the list of types for this run, whether infinite or lifecycle
    if Params.do_lifecycle:
        # Make cohort scaling array
        cohort_scale = Params.TFP_growth**(-np.arange(Params.total_T+1))
        cohort_scale_array = np.tile(np.reshape(cohort_scale,(Params.total_T+1,1)),(1,Params.sim_pop_size))
        
        # Make base consumer types for each education level
        DropoutType = cstwMPCagent(**Params.init_dropout)
        DropoutType.a_init = a_init
Ejemplo n.º 9
0
 def calcStats(self,aLvlNow,pLvlNow,MPCnow,TranShkNow,EmpNow,t_age,LorenzBool,ManyStatsBool):
     '''
     Calculate various statistics about the current population in the economy.
     
     Parameters
     ----------
     aLvlNow : [np.array]
         Arrays with end-of-period assets, listed by each ConsumerType in self.agents.
     pLvlNow : [np.array]
         Arrays with permanent income levels, listed by each ConsumerType in self.agents.
     MPCnow : [np.array]
         Arrays with marginal propensity to consume, listed by each ConsumerType in self.agents.
     TranShkNow : [np.array]
         Arrays with transitory income shocks, listed by each ConsumerType in self.agents.
     EmpNow : [np.array]
         Arrays with employment states: True if employed, False otherwise.
     t_age : [np.array]
         Arrays with periods elapsed since model entry, listed by each ConsumerType in self.agents.
     LorenzBool: bool
         Indicator for whether the Lorenz target points should be calculated.  Usually False,
         only True when DiscFac has been identified for a particular nabla.
     ManyStatsBool: bool
         Indicator for whether a lot of statistics for tables should be calculated. Usually False,
         only True when parameters have been estimated and we want values for tables.
         
     Returns
     -------
     None
     '''
     # Combine inputs into single arrays
     aLvl = np.hstack(aLvlNow)
     pLvl = np.hstack(pLvlNow)
     age  = np.hstack(t_age)
     TranShk = np.hstack(TranShkNow)
     Emp = np.hstack(EmpNow)
     
     # Calculate the capital to income ratio in the economy
     CohortWeight = self.PopGroFac**(-age)
     CapAgg = np.sum(aLvl*CohortWeight)
     IncAgg = np.sum(pLvl*TranShk*CohortWeight)
     KtoYnow = CapAgg/IncAgg
     self.KtoYnow = KtoYnow
     
     # Store Lorenz data if requested
     self.LorenzLong = np.nan
     if LorenzBool:
         order = np.argsort(aLvl)
         aLvl = aLvl[order]
         CohortWeight = CohortWeight[order]
         wealth_shares = getLorenzShares(aLvl,weights=CohortWeight,percentiles=self.LorenzPercentiles,presorted=True)
         self.Lorenz = wealth_shares
         if ManyStatsBool:
             self.LorenzLong = getLorenzShares(aLvl,weights=CohortWeight,percentiles=np.arange(0.01,1.0,0.01),presorted=True)                
     else:
         self.Lorenz = np.nan # Store nothing if we don't want Lorenz data
         
     # Calculate a whole bunch of statistics if requested
     if ManyStatsBool:
         # Reshape other inputs
         MPC  = np.hstack(MPCnow)
         
         # Sort other data items if aLvl and CohortWeight were sorted
         if LorenzBool:
             pLvl = pLvl[order]
             MPC  = MPC[order]
             TranShk = TranShk[order]
             age = age[order]
             Emp = Emp[order]
         aNrm = aLvl/pLvl # Normalized assets (wealth ratio)
         IncLvl = TranShk*pLvl # Labor income this period
             
         # Calculate overall population MPC and by subpopulations
         MPCannual = 1.0 - (1.0 - MPC)**4
         self.MPCall = np.sum(MPCannual*CohortWeight)/np.sum(CohortWeight)
         employed =  Emp
         unemployed = np.logical_not(employed)
         if self.T_retire > 0: # Adjust for the lifecycle model, where agents might be retired instead
             unemployed = np.logical_and(unemployed,age < self.T_retire)
             employed   = np.logical_and(employed,age < self.T_retire)
             retired    = age >= self.T_retire
         else:
             retired    = np.zeros_like(unemployed,dtype=bool)
         self.MPCunemployed = np.sum(MPCannual[unemployed]*CohortWeight[unemployed])/np.sum(CohortWeight[unemployed])
         self.MPCemployed   = np.sum(MPCannual[employed]*CohortWeight[employed])/np.sum(CohortWeight[employed])
         self.MPCretired    = np.sum(MPCannual[retired]*CohortWeight[retired])/np.sum(CohortWeight[retired])
         self.MPCbyWealthRatio = calcSubpopAvg(MPCannual,aNrm,self.cutoffs,CohortWeight)
         self.MPCbyIncome      = calcSubpopAvg(MPCannual,IncLvl,self.cutoffs,CohortWeight)
         
         # Calculate the wealth quintile distribution of "hand to mouth" consumers
         quintile_cuts = getPercentiles(aLvl,weights=CohortWeight,percentiles=[0.2, 0.4, 0.6, 0.8])
         wealth_quintiles = np.ones(aLvl.size,dtype=int)
         wealth_quintiles[aLvl > quintile_cuts[0]] = 2
         wealth_quintiles[aLvl > quintile_cuts[1]] = 3
         wealth_quintiles[aLvl > quintile_cuts[2]] = 4
         wealth_quintiles[aLvl > quintile_cuts[3]] = 5
         MPC_cutoff = getPercentiles(MPCannual,weights=CohortWeight,percentiles=[2.0/3.0]) # Looking at consumers with MPCs in the top 1/3
         these = MPCannual > MPC_cutoff
         in_top_third_MPC = wealth_quintiles[these]
         temp_weights = CohortWeight[these]
         hand_to_mouth_total = np.sum(temp_weights)
         hand_to_mouth_pct = []
         for q in range(1,6):
             hand_to_mouth_pct.append(np.sum(temp_weights[in_top_third_MPC == q])/hand_to_mouth_total)
         self.HandToMouthPct = np.array(hand_to_mouth_pct)
         
     else: # If we don't want these stats, just put empty values in history
         self.MPCall = np.nan
         self.MPCunemployed = np.nan
         self.MPCemployed = np.nan
         self.MPCretired = np.nan
         self.MPCbyWealthRatio = np.nan
         self.MPCbyIncome = np.nan
         self.HandToMouthPct = np.nan
Ejemplo n.º 10
0
        MrkvArray[t,t+1] = LivPrb[t]
    MrkvArray[t+1,0] = 1.0
    
    w, v = np.linalg.eig(np.transpose(MrkvArray))
    idx = (np.abs(w-1.0)).argmin()
    x = v[:,idx].astype(float)
    AgeDstn = (x/np.sum(x))
    return AgeDstn
    

# Set targets for K/Y and the Lorenz curve based on the data
if Params.do_liquid:
    lorenz_target = np.array([0.0, 0.004, 0.025,0.117])
    KY_target = 6.60
else: # This is hacky until I can find the liquid wealth data and import it
    lorenz_target = getLorenzShares(Params.SCF_wealth,weights=Params.SCF_weights,percentiles=Params.percentiles_to_match)
    lorenz_long_data = np.hstack((np.array(0.0),getLorenzShares(Params.SCF_wealth,weights=Params.SCF_weights,percentiles=np.arange(0.01,1.0,0.01).tolist()),np.array(1.0)))
    #lorenz_target = np.array([-0.002, 0.01, 0.053,0.171])
    KY_target = 10.26

# Make AgentTypes for estimation
if Params.do_lifecycle:
    DropoutType = cstwMPCagent(**Params.init_dropout)
    DropoutType.AgeDstn = calcStationaryAgeDstn(DropoutType.LivPrb,True)
    HighschoolType = deepcopy(DropoutType)
    HighschoolType(**Params.adj_highschool)
    HighschoolType.AgeDstn = calcStationaryAgeDstn(HighschoolType.LivPrb,True)
    CollegeType = deepcopy(DropoutType)
    CollegeType(**Params.adj_college)
    CollegeType.AgeDstn = calcStationaryAgeDstn(CollegeType.LivPrb,True)
    DropoutType.update()