class testPerfForesightConsumerType(unittest.TestCase): def setUp(self): self.agent = PerfForesightConsumerType() self.agent_infinite = PerfForesightConsumerType(cycles=0) PF_dictionary = { 'CRRA': 2.5, 'DiscFac': 0.96, 'Rfree': 1.03, 'LivPrb': [0.98], 'PermGroFac': [1.01], 'T_cycle': 1, 'cycles': 0, 'AgentCount': 10000 } self.agent_alt = PerfForesightConsumerType(**PF_dictionary) def test_default_solution(self): self.agent.solve() c = self.agent.solution[0].cFunc self.assertEqual(c.x_list[0], -0.9805825242718447) self.assertEqual(c.x_list[1], 0.01941747572815533) self.assertEqual(c.y_list[0], 0) self.assertEqual(c.y_list[1], 0.511321002804608) self.assertEqual(c.decay_extrap, False) def test_another_solution(self): self.agent_alt.DiscFac = 0.90 self.agent_alt.solve() self.assertAlmostEqual(self.agent_alt.solution[0].cFunc(10).tolist(), 3.9750093524820787) def test_checkConditions(self): self.agent_infinite.checkConditions() self.assertTrue(self.agent_infinite.conditions['AIC']) self.assertTrue(self.agent_infinite.conditions['GICPF']) self.assertTrue(self.agent_infinite.conditions['RIC']) self.assertTrue(self.agent_infinite.conditions['FHWC']) def test_simulation(self): self.agent_infinite.solve() # Create parameter values necessary for simulation SimulationParams = { "AgentCount": 10000, # Number of agents of this type "T_sim": 120, # Number of periods to simulate "aNrmInitMean": -6.0, # Mean of log initial assets "aNrmInitStd": 1.0, # Standard deviation of log initial assets "pLvlInitMean": 0.0, # Mean of log initial permanent income "pLvlInitStd": 0.0, # Standard deviation of log initial permanent income "PermGroFacAgg": 1.0, # Aggregate permanent income growth factor "T_age": None, # Age after which simulated agents are automatically killed } self.agent_infinite( **SimulationParams ) # This implicitly uses the assignParameters method of AgentType # Create PFexample object self.agent_infinite.track_vars = ['mNrmNow'] self.agent_infinite.initializeSim() self.agent_infinite.simulate() self.assertAlmostEqual( np.mean(self.agent_infinite.history['mNrmNow'], axis=1)[40], -23.008063500363942) self.assertAlmostEqual( np.mean(self.agent_infinite.history['mNrmNow'], axis=1)[100], -27.164608851546927) ## Try now with the manipulation at time step 80 self.agent_infinite.initializeSim() self.agent_infinite.simulate(80) self.agent_infinite.aNrmNow += -5. # Adjust all simulated consumers' assets downward by 5 self.agent_infinite.simulate(40) self.assertAlmostEqual( np.mean(self.agent_infinite.history['mNrmNow'], axis=1)[40], -23.008063500363942) self.assertAlmostEqual( np.mean(self.agent_infinite.history['mNrmNow'], axis=1)[100], -29.140261331951606)
PFexample(**SimulationParams) # %% [markdown] pycharm={"name": "#%% md\n"} # To generate simulated data, we need to specify which variables we want to track the "history" of for this instance. To do so, we set the $\texttt{track_vars}$ attribute of our $\texttt{PerfForesightConsumerType}$ instance to be a list of strings with the simulation variables we want to track. # # In this model, valid elments of $\texttt{track_vars}$ include $\texttt{mNrmNow}$, $\texttt{cNrmNow}$, $\texttt{aNrmNow}$, and $\texttt{pLvlNow}$. Because this model has no idiosyncratic shocks, our simulated data will be quite boring. # # ### Generating simulated data # # Before simulating, the $\texttt{initializeSim}$ method must be invoked. This resets our instance back to its initial state, drawing a set of initial $\texttt{aNrmNow}$ and $\texttt{pLvlNow}$ values from the specified distributions and storing them in the attributes $\texttt{aNrmNow_init}$ and $\texttt{pLvlNow_init}$. It also resets this instance's internal random number generator, so that the same initial states will be set every time $\texttt{initializeSim}$ is called. In models with non-trivial shocks, this also ensures that the same sequence of shocks will be generated on every simulation run. # # Finally, the $\texttt{simulate}$ method can be called. # %% pycharm={"name": "#%%\n"} PFexample.track_vars = ["mNrmNow"] PFexample.initializeSim() PFexample.simulate() # %% [markdown] pycharm={"name": "#%% md\n"} # Each simulation variable $\texttt{X}$ named in $\texttt{track_vars}$ will have the *history* of that variable for each agent stored in the attribute $\texttt{X_hist}$ as an array of shape $(\texttt{T_sim},\texttt{AgentCount})$. To see that the simulation worked as intended, we can plot the mean of $m_t$ in each simulated period: # %% pycharm={"name": "#%%\n"} plt.plot(np.mean(PFexample.history["mNrmNow"], axis=1)) plt.xlabel("Time") plt.ylabel("Mean normalized market resources") plt.show() # %% [markdown] pycharm={"name": "#%% md\n"} # A perfect foresight consumer can borrow against the PDV of his future income-- his human wealth-- and thus as time goes on, our simulated agents approach the (very negative) steady state level of $m_t$ while being steadily replaced with consumers with roughly $m_t=1$. # # The slight wiggles in the plotted curve are due to consumers randomly dying and being replaced; their replacement will have an initial state drawn from the distributions specified by the user. To see the current distribution of ages, we can look at the attribute $\texttt{t_age}$.
class testPerfForesightConsumerType(unittest.TestCase): def setUp(self): self.agent = PerfForesightConsumerType() self.agent_infinite = PerfForesightConsumerType(cycles=0) PF_dictionary = { "CRRA": 2.5, "DiscFac": 0.96, "Rfree": 1.03, "LivPrb": [0.98], "PermGroFac": [1.01], "T_cycle": 1, "cycles": 0, "AgentCount": 10000, } self.agent_alt = PerfForesightConsumerType(**PF_dictionary) def test_default_solution(self): self.agent.solve() c = self.agent.solution[0].cFunc self.assertEqual(c.x_list[0], -0.9805825242718447) self.assertEqual(c.x_list[1], 0.01941747572815533) self.assertEqual(c.y_list[0], 0) self.assertEqual(c.y_list[1], 0.511321002804608) self.assertEqual(c.decay_extrap, False) def test_another_solution(self): self.agent_alt.DiscFac = 0.90 self.agent_alt.solve() self.assertAlmostEqual(self.agent_alt.solution[0].cFunc(10).tolist(), 3.9750093524820787) def test_checkConditions(self): self.agent_infinite.checkConditions() self.assertTrue(self.agent_infinite.conditions["AIC"]) self.assertTrue(self.agent_infinite.conditions["GICPF"]) self.assertTrue(self.agent_infinite.conditions["RIC"]) self.assertTrue(self.agent_infinite.conditions["FHWC"]) def test_simulation(self): self.agent_infinite.solve() # Create parameter values necessary for simulation SimulationParams = { "AgentCount": 10000, # Number of agents of this type "T_sim": 120, # Number of periods to simulate "aNrmInitMean": -6.0, # Mean of log initial assets "aNrmInitStd": 1.0, # Standard deviation of log initial assets "pLvlInitMean": 0.0, # Mean of log initial permanent income "pLvlInitStd": 0.0, # Standard deviation of log initial permanent income "PermGroFacAgg": 1.0, # Aggregate permanent income growth factor "T_age": None, # Age after which simulated agents are automatically killed } self.agent_infinite( **SimulationParams ) # This implicitly uses the assignParameters method of AgentType # Create PFexample object self.agent_infinite.track_vars = ["mNrmNow"] self.agent_infinite.initializeSim() self.agent_infinite.simulate() self.assertAlmostEqual( np.mean(self.agent_infinite.history["mNrmNow"], axis=1)[40], -23.008063500363942, ) self.assertAlmostEqual( np.mean(self.agent_infinite.history["mNrmNow"], axis=1)[100], -27.164608851546927, ) ## Try now with the manipulation at time step 80 self.agent_infinite.initializeSim() self.agent_infinite.simulate(80) # This actually does nothing because aNrmNow is # epiphenomenal. Probably should change mNrmNow instead self.agent_infinite.state_now['aNrmNow'] += (-5.0) self.agent_infinite.simulate(40) self.assertAlmostEqual( np.mean(self.agent_infinite.history["mNrmNow"], axis=1)[40], -23.008063500363942, ) self.assertAlmostEqual( np.mean(self.agent_infinite.history["mNrmNow"], axis=1)[100], -29.140261331951606, )