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_check_conditions(self): self.agent_infinite.check_conditions() self.assertTrue(self.agent_infinite.conditions["AIC"]) self.assertTrue(self.agent_infinite.conditions["GICRaw"]) 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.assign_parameters( **SimulationParams ) # This implicitly uses the assign_parameters method of AgentType # Create PFexample object self.agent_infinite.track_vars = ["mNrm"] self.agent_infinite.initialize_sim() self.agent_infinite.simulate() self.assertAlmostEqual( np.mean(self.agent_infinite.history["mNrm"], axis=1)[40], -23.008063500363942, ) self.assertAlmostEqual( np.mean(self.agent_infinite.history["mNrm"], axis=1)[100], -27.164608851546927, ) ## Try now with the manipulation at time step 80 self.agent_infinite.initialize_sim() self.agent_infinite.simulate(80) # This actually does nothing because aNrmNow is # epiphenomenal. Probably should change mNrmNow instead self.agent_infinite.state_now['aNrm'] += (-5.0) self.agent_infinite.simulate(40) self.assertAlmostEqual( np.mean(self.agent_infinite.history["mNrm"], axis=1)[40], -23.008063500363942, ) self.assertAlmostEqual( np.mean(self.agent_infinite.history["mNrm"], axis=1)[100], -29.140261331951606, ) def test_stable_points(self): # Solve the constrained agent. Stable points exists only with a # borrowing constraint. constrained_agent = PerfForesightConsumerType(cycles=0, BoroCnstArt=0.0) constrained_agent.solve() # Check against pre-computed values. self.assertEqual(constrained_agent.solution[0].mNrmStE, 1.0) # Check that they are both the same, since the problem is deterministic self.assertEqual(constrained_agent.solution[0].mNrmStE, constrained_agent.solution[0].mNrmTrg)
def plot1(Epsilon, DiscFac, PopGrowth, YearsPerGeneration, Initialk): '''Inputs: Epsilon: Elasticity of output with respect to capital/labour ratio DiscFac: One period discount factor YearPerGeneration: No. of years per generation PopGrowth: Gross growth rate of population in one period''' # kMax = 0.1 # Define some parameters Beta = DiscFac**YearsPerGeneration xi = PopGrowth**YearsPerGeneration Q = (1-Epsilon)*(Beta/(1+Beta))/xi kBar = Q**(1/(1-Epsilon)) # Create an agent that will solve the consumption problem PFagent = PerfForesightConsumerType(**init_perfect_foresight) PFagent.cycles = 1 # let the agent live the cycle of periods just once PFagent.T_cycle = 2 # Number of periods in the cycle PFagent.assign_parameters(PermGroFac = [0.000001]) # Income only in the first period PFagent.LivPrb = [1.] PFagent.DiscFac = Beta # Hark seems to have trouble with log-utility # so pass rho = 1 + something small. PFagent.CRRA = 1.001 PFagent.solve() # Plot the OLG capital accumulation curve and 45 deg line plt.figure(figsize=(9,6)) kt_range = np.linspace(0, kMax, 300) # Analitical solution plot ktp1 = Q*kt_range**Epsilon plt.plot(kt_range, ktp1, 'b-', label='Capital accumulation curve') plt.plot(kt_range, kt_range, 'k-', label='45 Degree line') # Plot the path kt_ar = Initialk ktp1_ar = 0. for i in range(3): # Compute Next Period's capital using HARK wage = (1-Epsilon)*kt_ar**Epsilon c = PFagent.solution[0].cFunc(wage) a = wage - c k1 = a/xi plt.arrow(kt_ar, ktp1_ar, 0., k1-ktp1_ar, length_includes_head=True, lw=0.01, width=0.0005, color='black', edgecolor=None) plt.arrow(kt_ar, k1, k1-kt_ar , 0., length_includes_head=True, lw=0.01, width=0.0005, color='black', edgecolor=None) # Update arrow kt_ar = k1 ktp1_ar = kt_ar # Plot kbar and initial k plt.plot(kBar, kBar, 'ro', label=r'$\bar{k}$') plt.plot(Initialk, 0.0005, 'co', label = '$k_0$') plt.legend() plt.xlim(0 ,kMax) plt.ylim(0, kMax) plt.xlabel('$k_t$') plt.ylabel('$k_{t+1}$') plt.show() return None
# # The cell below puts these parameters into a dictionary, then gives them to `PFexample`. Note that all of these parameters *could* have been passed as part of the original dictionary; we omitted them above for simplicity. # %% {"pycharm": {"name": "#%%\n"}} 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 } PFexample.assign_parameters(**SimulationParams) # %% [markdown] {"incorrectly_encoded_metadata": "pycharm= [markdown] {\"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 `track_vars` attribute of our `PerfForesightConsumerType` instance to be a list of strings with the simulation variables we want to track. # # In this model, valid arguments to `track_vars` include $\texttt{mNrm}$, $\texttt{cNrm}$, $\texttt{aNrm}$, and $\texttt{pLvl}$. Because this model has no idiosyncratic shocks, our simulated data will be quite boring. # # ### Generating simulated data # # Before simulating, the `initialize_sim` method must be invoked. This resets our instance back to its initial state, drawing a set of initial $\texttt{aNrm}$ and $\texttt{pLvl}$ 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 `initialize_sim` 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 `simulate` method can be called. # %% {"pycharm": {"name": "#%%\n"}} PFexample.track_vars = ['mNrm'] PFexample.initialize_sim()